<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      canvas {
        display: block;
        width: 100vw;
        height: 100vh;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas"></canvas>
    <script>
      const canvas = document.getElementById("canvas");
      // 设置 canvas 的宽高
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      // 获取webgl上下文
      const gl = canvas.getContext("webgl");

      // 创建顶点着色器
      const vShader = gl.createShader(gl.VERTEX_SHADER);
      // 顶点着色器代码
      gl.shaderSource(
        vShader,
        `
        attribute vec4 a_position;
        void main() {
          gl_Position = a_position;
        }
      `
      );
      // 编译顶点着色器
      gl.compileShader(vShader);

      // 创建片元着色器
      const fShader = gl.createShader(gl.FRAGMENT_SHADER);
      // 片元着色器代码
      gl.shaderSource(
        fShader,
        `
        void main() {
          gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
        }
      `
      );
      // 编译片元着色器
      gl.compileShader(fShader);
      // 创建程序对象
      const program = gl.createProgram();
      // 将顶点着色器和片元着色器关联到程序对象中
      gl.attachShader(program, vShader);
      gl.attachShader(program, fShader);
      // 链接程序对象
      gl.linkProgram(program);
      // 使用程序对象
      gl.useProgram(program);

      // 创建顶点数据
      const position = gl.getAttribLocation(program, "a_position");
      // 创建数据缓冲区
      const buffer = gl.createBuffer();
      // 绑定缓冲区
      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);

      // 设置顶点数据
      gl.bufferData(
        gl.ARRAY_BUFFER,
        new Float32Array([0, 0.5, -0.5, -0.5, 0.5, -0.5]),
        gl.STATIC_DRAW // 静态绘制
      );
      // 设置顶点属性
      gl.vertexAttribPointer(
        position, //告诉attribute变量从缓冲区中获取数据
        2, // 每次迭代提供2个单位的数据
        gl.FLOAT, //数据类型
        false, //是否进行归一化
        0, // 步长，每次迭代需要获取多少个单位数据
        0 // 偏移量，从缓冲区中的第几个单位数据开始取数据
      );
      // 启用顶点属性
      gl.enableVertexAttribArray(position);

      // 绘制三角形
      gl.drawArrays(gl.TRIANGLES, 0, 3);
    </script>
  </body>
</html>
